package com.uyayo.oms.system.freemarker;

import com.uyayo.framework.common.util.ValidateUtil;
import com.uyayo.system.config.entity.SysDictionaryData;
import com.uyayo.system.config.service.SysDictionaryService;
import freemarker.core.Environment;
import freemarker.template.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * Created by hfj on 2017/6/8.
 */
public class DictionaryDirective implements TemplateDirectiveModel {
    @Autowired
    private SysDictionaryService sysDictionaryService;

    @Override
    public void execute(Environment environment, Map params, TemplateModel[] templateModels, TemplateDirectiveBody templateDirectiveBody) throws TemplateException, IOException {

        String str = "";
        String type = getRequiredParam(params, "type");
        if (!StringUtils.isEmpty(type)){
            if (type.equalsIgnoreCase("function")){
                str = getFunction(params);
            }else if (type.equalsIgnoreCase("listjson")){
                str = getListJsonObjByOutString(params);
            }else if (type.equalsIgnoreCase("treejson")){
                str = getTreeJsonObjByOutString(params);
            }

        }
        environment.getOut().write(str);

    }


    /**
     * 获取字典树JavaScript的JSON对象-最终返回字符串
     * @param params
     * @return
     */
    private  String getTreeJsonObjByOutString(Map params) throws TemplateException {

        StringBuffer sb = new StringBuffer();
        String fields = getRequiredParam(params, "fields");
        sb.append("<script type=\"text/javascript\">\n");
        if (ValidateUtil.isNotEmpty(fields)) {
            String[] arrayFields = fields.split(",");
            for (int i = 0; i < arrayFields.length; i++) {
                if (arrayFields[i].indexOf(":") != -1) {
                    String field = arrayFields[i].substring(0,
                            arrayFields[i].indexOf(":"));
                    List<SysDictionaryData> dictionaries = sysDictionaryService
                            .selectSysDictinaryDataByCode(field);
                    sb.append(getTreeJsonObj(field, dictionaries));
                } else {
                    List<SysDictionaryData> dictionaries = sysDictionaryService
                            .selectSysDictinaryDataByCode(arrayFields[i]);
                    sb.append(getTreeJsonObj(arrayFields[i], dictionaries));
                }
            }
        }
        sb.append("\n</script>");

        return sb.toString();
    }



    public StringBuffer getlistTreeNodesForMap(Long parentId,
                                               StringBuffer returnStr, List<SysDictionaryData> list,
                                               List<SysDictionaryData> children_) {
        for (int i = 0; i < children_.size(); i++) {
            SysDictionaryData dictionary = children_.get(i);
            if (parentId.equals(dictionary.getParentId())) {
                List<SysDictionaryData> children = new ArrayList<>();
                int sum = 0;
                for (SysDictionaryData dictionary_ : list) {
                    if (dictionary.getId().equals(
                            dictionary_.getParentId())) {
                        children.add(dictionary_);
                        if (sum == 0) {
                            returnStr.append("{id:'" + dictionary.getValue()
                                    + "',");
                            returnStr.append("text:'" + dictionary.getName()
                                    + "',");
                            if (dictionary.getIconCls() != null
                                    && !"".equals(dictionary.getIconCls())) {
                                returnStr.append("iconCls:'"
                                        + dictionary.getIconCls() + "',");
                            }
                            returnStr.append("children:[");
                            getlistTreeNodesForMap(dictionary.getId(),
                                    returnStr, list, children);

                        } else {
                            if (i + 1 == children_.size()) {
                                returnStr.append("{id:'"
                                        + dictionary_.getValue() + "',");
                                if (dictionary_.getIconCls() != null
                                        && !"".equals(dictionary_.getIconCls())) {
                                    returnStr.append("iconCls:'"
                                            + dictionary_.getIconCls() + "',");
                                }
                                returnStr.append("text:'"
                                        + dictionary_.getName() + "'}]}");
                            } else {
                                returnStr.append("{id:'"
                                        + dictionary_.getValue() + "',");
                                if (dictionary_.getIconCls() != null
                                        && !"".equals(dictionary_.getIconCls())) {
                                    returnStr.append("iconCls:'"
                                            + dictionary_.getIconCls() + "',");
                                }
                                returnStr.append("text:'"
                                        + dictionary_.getName() + "'},");
                            }
                        }
                        sum++;
                    }
                }
                if (children == null || children.size() <= 0) {
                    if (i == 0) {
                        returnStr.append("{id:'" + dictionary.getValue()
                                + "',");
                        if (dictionary.getIconCls() != null
                                && !"".equals(dictionary.getIconCls())) {
                            returnStr.append("iconCls:'"
                                    + dictionary.getIconCls() + "',");
                        }
                        returnStr.append("text:'" + dictionary.getName()
                                + "'},");
                    } else {
                        returnStr.append("{id:'" + dictionary.getValue()
                                + "',");
                        returnStr.append("iconCls:'" + dictionary.getIconCls()
                                + "',");
                        returnStr.append("text:'" + dictionary.getName()
                                + "'},");
                    }
                }
            }
        }
        return returnStr;
    }

    /**
     * 获取字典列表JavaScript的JSON对象
     * @param field
     * @param sysDictionaryDatas
     * @return String
     */
    public String getTreeJsonObj(String field,
                                      List<SysDictionaryData> sysDictionaryDatas) {
        StringBuffer str = new StringBuffer("var ");
        str.append(field).append("_TreeStore = [");
        StringBuffer returnStr = new StringBuffer(" ");
        for (SysDictionaryData sysDictionaryData : sysDictionaryDatas) {
            if (sysDictionaryData.getCode().equals(field)) {
                Long id = sysDictionaryData.getId();
                List<SysDictionaryData> children = new ArrayList<>();
                for (SysDictionaryData sysDictionaryData_ : sysDictionaryDatas) {
                    if (sysDictionaryData.getId().equals(
                            sysDictionaryData_.getParentId())) {
                        children.add(sysDictionaryData_);
                    }
                }
                returnStr = getlistTreeNodesForMap(id, returnStr,
                        sysDictionaryDatas, children);
                str.append(returnStr);
            }
        }

        str.append("];");
        return str.toString();
    }


    /**
     * 获取字典列表JavaScript的JSON对象-最终返回字符串
     * @param params
     * @return
     * @throws TemplateException
     */
    private  String getListJsonObjByOutString(Map params) throws TemplateException {
        StringBuffer sb = new StringBuffer();
        sb.append("<script type=\"text/javascript\">\n");
        String fields = getRequiredParam(params, "fields");
        if (ValidateUtil.isNotEmpty(fields)) {
            String[] arrayFields = fields.split(",");
            for (int i = 0; i < arrayFields.length; i++) {
                if (arrayFields[i].indexOf(":") != -1) {
                    String field = arrayFields[i].substring(0, arrayFields[i].indexOf(":"));

                    List<SysDictionaryData> dictionaries = sysDictionaryService.selectSysDictinaryDataByCode(field);
                    sb.append(getListJsonObj(field, dictionaries));
                } else {

                    List<SysDictionaryData> dictionaries = sysDictionaryService.selectSysDictinaryDataByCode(arrayFields[i]);
                    sb.append(getListJsonObj(arrayFields[i], dictionaries));
                }
            }
        }
        sb.append("\n</script>");

        return  sb.toString();
    }


    /**
     * 获取字典列表JavaScript的JSON对象
     * @param field
     * @param sysDictionaryDataList
     * @return
     */
    public String getListJsonObj(String field, List<SysDictionaryData> sysDictionaryDataList) {
        StringBuffer str = new StringBuffer("var ");
        str.append(field).append("Store = [");
        int sum = 0;
        for (SysDictionaryData dictionaryData : sysDictionaryDataList) {
            if (sum != 0) {
                str.append(",");
            }
            str.append("{id:'").append(dictionaryData.getValue()).append("',value:'").append(dictionaryData.getValue()).append("',text:'")
                    .append(dictionaryData.getName()).append("'}");
            sum++;
        }
        str.append("];");
        return str.toString();
    }

    /**
     * 获取字典JavaScript方法
     * @param params
     * @return
     * @throws TemplateException
     */
    private  String getFunction(Map params) throws TemplateException {
        StringBuffer sb = new StringBuffer();
        String fields = getRequiredParam(params, "fields");
        String[] arrayFields = fields.split(",");
        sb.append("<script type=\"text/javascript\">\n");
        for (int i = 0; i < arrayFields.length; i++)
        {
            List<SysDictionaryData> dictionaries = sysDictionaryService.selectSysDictinaryDataByCode(arrayFields[i]);
            sb.append(getDictNameFunction(arrayFields[i], dictionaries));
        }
        sb.append("\n</script>");
        return sb.toString();
    }


    /**
     * 获取字典名称的方法
     * @param field
     * @param dictionarys
     * @return
     */
    private String getDictNameFunction(String field, List<SysDictionaryData> dictionarys) {
        StringBuffer str = new StringBuffer("");
        str.append("function get").append(field).append("DictName(value) {");
        for (SysDictionaryData dictionary : dictionarys) {
            str.append("if(value=='").append(dictionary.getValue())
                    .append("') return '").append(dictionary.getName())
                    .append("';");
        }
        str.append("return value;");
        str.append("}");
        return str.toString();
    }






    /**
     * 获取参数值
     * @param params
     * @param key
     * @return
     * @throws TemplateException
     */
    private String getRequiredParam(Map params,String key) throws TemplateException {
        Object value = params.get(key);
        if(value == null || StringUtils.isEmpty(value.toString())) {
            throw new TemplateModelException("not found required parameter:"+key+" for directive");
        }
        return value.toString();
    }

    /**
     * 获取参数值
     * @param params
     * @param key
     * @param defaultValue
     * @return
     * @throws TemplateException
     */
    private String getParam(Map params,String key,String defaultValue){
        Object value = params.get(key);
        return value == null ? defaultValue : value.toString();
    }
}
